/**
 * CustomOutline 类 - Three.js 的轮廓线效果管理器
 * 提供了一个完整的轮廓线效果系统，支持：
 * - 可配置的轮廓线参数（颜色、宽度、透明度等）
 * - 多个物体的轮廓线效果
 * - 独立控制物体的轮廓线效果
 * - 动态启用/禁用轮廓线系统
 */

import * as THREE from 'three'
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js'
import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js'
import { OutlinePass } from 'three/examples/jsm/postprocessing/OutlinePass.js'
import { OutputPass } from 'three/examples/jsm/postprocessing/OutputPass.js'

/**
 * 默认的轮廓线效果参数配置
 */
const DEFAULT_OUTLINE_OPTIONS = {
  edgeStrength: 3.0, // 轮廓线强度
  edgeGlow: 0.0, // 轮廓线发光强度
  edgeThickness: 1.0, // 轮廓线粗细
  pulsePeriod: 0, // 轮廓线闪烁周期（0为不闪烁）
  usePatternTexture: false, // 是否使用纹理
  visibleEdgeColor: new THREE.Color(0xffffff), // 可见部分轮廓线颜色
  hiddenEdgeColor: new THREE.Color(0x190a05), // 被遮挡部分轮廓线颜色
  opacity: 1.0, // 轮廓线透明度
}

export default class CustomOutline {
  /**
   * 创建一个新的轮廓线效果实例
   * @param {THREE.Scene} scene - Three.js 场景实例
   * @param {THREE.Camera} camera - Three.js 相机实例
   * @param {THREE.WebGLRenderer} renderer - Three.js 渲染器实例
   */
  constructor(scene, camera, renderer) {
    this._scene = scene
    this._camera = camera
    this._renderer = renderer
    this._selectedObjects = []
    this._enabled = true

    this._initOutlineEffect()
  }

  /**
   * 初始化轮廓线效果的各个组件
   * @private
   */
  _initOutlineEffect() {
    // 创建效果合成器
    this._composer = new EffectComposer(this._renderer)

    // 添加场景渲染通道
    const renderPass = new RenderPass(this._scene, this._camera)
    this._composer.addPass(renderPass)

    // 创建轮廓线通道
    this._outlinePass = new OutlinePass(
      new THREE.Vector2(window.innerWidth, window.innerHeight),
      this._scene,
      this._camera,
    )

    // 设置默认参数
    this.setOutlineParameters()

    // 添加轮廓线通道
    this._composer.addPass(this._outlinePass)

    // 添加输出通道
    const outputPass = new OutputPass()
    this._composer.addPass(outputPass)
  }

  /**
   * 更新轮廓线效果的参数配置
   * @param {Object} options - 轮廓线参数配置对象
   */
  setOutlineParameters(options = {}) {
    const params = { ...DEFAULT_OUTLINE_OPTIONS, ...options }

    Object.entries(params).forEach(([key, value]) => {
      if (key in this._outlinePass) {
        this._outlinePass[key] = value
      }
    })
  }

  /**
   * 添加要显示轮廓线的物体
   * @param {THREE.Object3D|Array<THREE.Object3D>} objects - 要添加轮廓线的物体或物体数组
   */
  addSelectedObjects(objects) {
    const objectsArray = Array.isArray(objects) ? objects : [objects]

    objectsArray.forEach((object) => {
      if (!this._selectedObjects.includes(object)) {
        this._selectedObjects.push(object)
      }
    })

    this._outlinePass.selectedObjects = this._selectedObjects
  }

  /**
   * 移除物体的轮廓线效果
   * @param {THREE.Object3D|Array<THREE.Object3D>} objects - 要移除轮廓线的物体或物体数组
   */
  removeSelectedObjects(objects) {
    const objectsArray = Array.isArray(objects) ? objects : [objects]

    this._selectedObjects = this._selectedObjects.filter(
      (selected) => !objectsArray.includes(selected),
    )

    this._outlinePass.selectedObjects = this._selectedObjects
  }

  /**
   * 清除所有轮廓线效果
   */
  clearSelectedObjects() {
    this._selectedObjects = []
    this._outlinePass.selectedObjects = []
  }

  /**
   * 获取当前所有具有轮廓线效果的物体
   * @returns {Array<THREE.Object3D>} 具有轮廓线效果的物体数组
   */
  getSelectedObjects() {
    return [...this._selectedObjects]
  }

  /**
   * 更新轮廓线效果的渲染尺寸
   * @param {number} width - 新的渲染宽度
   * @param {number} height - 新的渲染高度
   */
  setSize(width, height) {
    this._composer.setSize(width, height)
  }

  /**
   * 设置轮廓线的可见边缘颜色
   * @param {THREE.Color|string|number} color - 新的颜色值
   */
  setVisibleEdgeColor(color) {
    this._outlinePass.visibleEdgeColor = new THREE.Color(color)
  }

  /**
   * 设置轮廓线的隐藏边缘颜色
   * @param {THREE.Color|string|number} color - 新的颜色值
   */
  setHiddenEdgeColor(color) {
    this._outlinePass.hiddenEdgeColor = new THREE.Color(color)
  }

  /**
   * 销毁轮廓线效果，释放资源
   */
  dispose() {
    this.clearSelectedObjects()
    this._outlinePass.dispose()
    this._composer.dispose()

    // 清理引用
    this._outlinePass = null
    this._composer = null
    this._selectedObjects = null
  }

  /**
   * 临时禁用轮廓线效果，但保留配置
   */
  disable() {
    this._enabled = false
  }

  /**
   * 重新启用之前禁用的轮廓线效果
   */
  enable() {
    this._enabled = true
  }

  /**
   * 执行轮廓线效果的渲染
   */
  render() {
    if (!this._enabled) {
      // 如果禁用了轮廓线效果，直接使用普通渲染
      this._renderer.render(this._scene, this._camera)
      return
    }

    this._composer.render()
  }
}
